/* remixed from: polyScrewThread_r1.scad    by aubenc @ Thingiverse
 * http://www.thingiverse.com/thing:8796
 * remixed from: https://www.thingiverse.com/thing:2664046/files
 */

PI=3.141592;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 
// A lid for screw a screw jar
// A screw jar for above lid
//
lidDiameter = 30;       //od: Outer diameter of the thread 
lidHeight = 10;         //hg:  the height of the lid
lidTotalHeight = 20;    //tl:   Total length of object (tl = lt + unthreaded_length)
lidTolerance = 0.5;     // tolerance between lid and jar threads
lidTopThick = 2;        //tt: top thickness
lidWall=2;              //wt:   wall thickness
lidBottom=0;            //bt:   base thickness (may be zero)
lidTop=0;               //tt:   top thickness (may be zero)
lidThreadHeight=4;      //sth: Step height (the half will be used to countersink the ends)
lidThreadDegrees=55;    //lf0:  Step shape degrees.  Step, traveling length per turn
lidResolution=0.5;      //rs: Resolution -- set small values to minimize overhang issues
lidThreadLen=11;        //lt:   Length of the threaded section of the screw.  Length (Z) of the tread
lidCounterSink=2;       //rs:   Resolution (face at each 2mm of the perimeter)
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Lid
screwLid(  lidDiameter,    //od: Outer diameter of the thread to match
            lidWall,        //wt: wall_thickness. The thickness of the outer walls
            lidTopThick,    //tt: top thickness
            lidHeight,      //hg:  the height of the lid
            lidThreadHeight,//sth: Step height (the half will be used to countersink the ends)
            lidThreadDegrees,  //lf0: Degrees (same as used for the screw_thread example)
            lidResolution   //rs: Resolution -- set small values to minimize overhang issues
);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Jar
translate([0,0,lidTotalHeight+lidTopThick])
rotate([0,180,0])
translate([0,0,0])  //25
hollowScrewThread(  lidDiameter - lidTolerance*2,   //od:   Outer diameter of the thread
                    lidWall,            //wt:   wall thickness
                    lidBottom,          //bt:   base thickness (may be zero)
                    lidTop,             //tt:   top thickness (may be zero)
                    lidThreadHeight,    //sth:  Thread step 
                    lidThreadDegrees,   //lf0:  Step shape degrees.  Step, traveling length per turn
                    lidThreadLen,       //lt:   Length of the threaded section of the screw.  Length (Z) of the tread
                    lidTotalHeight,     //tl:   Total length of object (tl = lt + unthreaded_length)  
                    lidResolution,      //rs:   Resolution (face at each 2mm of the perimeter)
                    lidCounterSink      //cs:   Countersink in both ends
);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
module hollowScrewThread(od, wt, bt, tt, sth, lf0, lt, tl, rs, cs) {  //kt added  
  //Purpose: This creates a tube that may be optionally capped at either end (top or base)
  //         One end may be threaded for a specified distance.  
  //od:   Outer diameter of the thread
  //wt:   wall thickness
  //bt:   base thickness (may be zero)
  //tt:   top thickness (may be zero)
  //sth:  Thread step
  //lf0:  Step shape degrees.  Step, traveling length per turn, also, tooth height, whatever...   
  //lt:   Length of the threaded section of the screw.  Length (Z) of the tread
  //tl:   Total length of object (tl = lt + unthreaded_length)
  //rs:   Resolution (face at each 2mm of the perimeter)
  //cs:   Countersink in both ends.  Countersink style:
  //         -2 - Not even flat ends
  //         -1 - Bottom (countersink'd and top flat)
  //          0 - None (top and bottom flat)
  //          1 - Top (bottom flat)
  //          2 - Both (countersink'd)  
  
  id = od - wt*2;  
  ntl = tl - lt;
  extra_z_for_bt = 1;
  extra_z_for_tt = 1;
  cutout_z = tl - tt - bt;
  
  difference() {
    //screw_thread(od, sth, lf0, lt, rs, cs);    
    hex_screw(od,    //od :  Outer diameter of the thread
              sth,   //sth:  Thread step
              lf0,   //lf0:  Step shape degrees
              lt,    //lt:   Length of the threaded section of the screw
              rs,    //rs:   Resolution (face at each 2mm of the perimeter)
              cs,    //cs:   Countersink in both ends
              0,     //df:   Distance between flats for the hex head
              0,     //hg:   Height of the hex head (can be zero)
              ntl,   //ntl:  Length of the non threaded section of the screw (can be zero)
              0      //ntd:  Diameter for the non threaded section of the screw
                        //     -1 - Same as inner diameter of the thread
                        //      0 - Same as outer diameter of the thread
                        //  value - The given value
    );     
    if ((bt == 0) && (tt == 0)) {   
      translate([0,0, -extra_z_for_bt])
        cylinder(d=id, h=cutout_z + extra_z_for_bt + extra_z_for_tt, $fn=100);    
    } else if ((bt == 0) && (tt != 0)) {    
      translate([0,0,bt - extra_z_for_bt])
        cylinder(d=id, h=cutout_z + extra_z_for_bt, $fn=100);    
    } else if ((bt != 0) && (tt == 0)) {    
      translate([0,0,bt])
        cylinder(d=id, h=cutout_z + extra_z_for_tt, $fn=100);    
    } else if ((bt != 0) && (tt != 0)) {    
      translate([0,0,0])
        cylinder(d=id, h=cutout_z, $fn=100);    
    }  
  }    
}  
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
module screwLid(cod, wt, tt, hg, sth, lf0, rs) 
{ //kt added
  //cod:  Outer diameter of the thread to match
  //wt:   outer wall thickness
  //tt:   top wall thickness
  //hg:   the height of the lid
  //sth:  Step height (the half will be used to countersink the ends)
  //lf0:  Degrees (same as used for the screw_thread example)
  //rs:   Resolution, set to small values to minimize overhang issues
  
  //cod2 = df - wt*2;
  df = cod + wt*2;
  chg = sth/2;
  
  difference() 
  {
    roundHead(hg,df);
    
    translate([0,0,hg-chg+0.1])  //top countersink
      cylinder(h=chg+0.01, 
               r1=cod/2-(chg+0.1)*cos(lf0)/sin(lf0),
               r2=cod/2, 
               $fn=floor(cod*PI/rs), center=false);
    translate([0,0,tt]) 
    {
      difference() 
      {
        screw_thread(cod, sth, lf0, hg, rs, -2);
        translate([0,0,-5]) cylinder(d=df,h=5);
      }
    }
  }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
module roundHead(hg,df)  
{ //kt added
  //hg:  Height 
  //df:  diameter of outside (bevel will begin at radius-1 mm)
  df0 = df-2;
  
	rd0=df0/2/sin(60);
	x0=0;	x1=df0/2;	x2=x1+hg/2;
	y0=0;	y1=hg/2;	y2=hg;

	intersection() 
	{
        cylinder(h=hg, r=df/2, $fn=100, center=false);
        rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5))
		  polygon([ [x0,y0],[x1,y0],[x2,y1],[x2,y2],[x0,y2] ]);
	}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
module screw_thread(od,sth,lf0,lt,rs,cs)  
{
  //od:   Outer diameter of the thread
  //sth:   Thread step 
  //lf0:  Step shape degrees.  Step, traveling length per turn, also, tooth height, whatever...   
  //lt:   Length of the threaded section of the screw.  Length (Z) of the tread
  //rs:   Resolution (face at each 2mm of the perimeter)
  //cs:   Countersink in both ends.  Countersink style:
  //         -2 - Not even flat ends
  //         -1 - Bottom (countersink'd and top flat)
  //          0 - None (top and bottom flat)
  //          1 - Top (bottom flat)
  //          2 - Both (countersink'd)      
  or=   od/2;                       //outer radius
  ir=   or-sth/2*cos(lf0)/sin(lf0);  
  pf=   2*PI*or;                    //outer circumference
  sn=   floor(pf/rs);
  lfxy= 360/sn;
  ttn=  round(lt/sth+1);
  zt=   sth/sn;

    intersection() 
    {
        if (cs >= -1) 
        {
            thread_shape(cs,lt,or,ir,sn,sth);
        }
        full_thread(ttn,sth,sn,zt,lfxy,or,ir);
    }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
module hex_screw(od,sth,lf0,lt,rs,cs,df,hg,ntl,ntd) {
  //od :  Outer diameter of the thread
  //sth:  Thread step
  //lf0:  Step shape degrees
  //lt:   Length of the threaded section of the screw
  //rs:   Resolution (face at each 2mm of the perimeter)
  //cs:   Countersink in both ends
  //df:   Distance between flats for the hex head
  //hg:   Height of the hex head (can be zero)
  //ntl:  Length of the non threaded section of the screw (can be zero)
  //ntd:  Diameter for the non threaded section of the screw
  //                    -1 - Same as inner diameter of the thread
  //                     0 - Same as outer diameter of the thread
  //                 value - The given value
  
  ntr=od/2-(sth/2)*cos(lf0)/sin(lf0);

  union() {
    hex_head(hg,df);
    translate([0,0,hg])
    if ( ntl == 0 ) {
      cylinder(h=0.01, r=ntr, center=true);
    } else {
      if ( ntd == -1 ) {
        cylinder(h=ntl+0.01, r=ntr, $fn=floor(od*PI/rs), center=false);
      }
      else if ( ntd == 0 ) {
        union() {
          cylinder(h=ntl-sth/2,
                   r=od/2, $fn=floor(od*PI/rs), center=false);
          translate([0,0,ntl-sth/2])
          cylinder(h=sth/2,
                   r1=od/2, r2=ntr, 
                   $fn=floor(od*PI/rs), center=false);
        }
      } else {
        cylinder(h=ntl, r=ntd/2, $fn=ntd*PI/rs, center=false);
      }
    }
    translate([0,0,ntl+hg]) screw_thread(od,sth,lf0,lt,rs,cs);
  }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
module thread_shape(cs,lt,or,ir,sn,sth)  {
  //cs:   Countersink in both ends.  Countersink style:
  //         -2 - Not even flat ends
  //         -1 - Bottom (countersink'd and top flat)
  //          0 - None (top and bottom flat)
  //          1 - Top (bottom flat)
  //          2 - Both (countersink'd)      
  //lt:   Length of the threaded section of the screw.  Length (Z) of the tread
  //or:   Outer radius of the thread (od/2 :  Half outer diameter of the thread)
  //ir:   Inner radius of the thread
  //sn:   value for $fn  
  //sth:   Thread step
  
  if ( cs == 0 ) {
    cylinder(h=lt, r=or, $fn=sn, center=false);
  } else {
    union() {
      translate([0,0,sth/2])
        cylinder(h=lt-sth+0.005, r=or, $fn=sn, center=false);

      if ( cs == -1 || cs == 2 ) {
        cylinder(h=sth/2, r1=ir, r2=or, $fn=sn, center=false);
      } else {
        cylinder(h=sth/2, r=or, $fn=sn, center=false);
      }

      translate([0,0,lt-sth/2])
      if ( cs == 1 || cs == 2 ) {
        cylinder(h=sth/2, r1=or, r2=ir, $fn=sn, center=false);
      } else {
        cylinder(h=sth/2, r=or, $fn=sn, center=false);
      }
    }
  }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
module full_thread(ttn,sth,sn,zt,lfxy,or,ir) {
  
  if (ir >= 0.2) {
    for (i=[0:ttn-1]) {
      for (j=[0:sn-1]) {
        //kt mod 11/21/17 -- removed assign()           
        pt = [[0,                  0,                  i*sth-sth            ],
              [ir*cos(j*lfxy),     ir*sin(j*lfxy),     i*sth+j*zt-sth       ],
              [ir*cos((j+1)*lfxy), ir*sin((j+1)*lfxy), i*sth+(j+1)*zt-sth   ],
              [0,                  0,                  i*sth                ],
              [or*cos(j*lfxy),     or*sin(j*lfxy),     i*sth+j*zt-sth/2     ],
              [or*cos((j+1)*lfxy), or*sin((j+1)*lfxy), i*sth+(j+1)*zt-sth/2 ],
              [ir*cos(j*lfxy),     ir*sin(j*lfxy),     i*sth+j*zt           ],
              [ir*cos((j+1)*lfxy), ir*sin((j+1)*lfxy), i*sth+(j+1)*zt       ],
              [0,                  0,                  i*sth+sth            ]	];
        //kt mod 11/21/17 -- changed 'triangles=' to 'faces=' 
        //   according to compiler warning
        polyhedron(points=pt,
                  faces=[	[1,0,3],[1,3,6],[6,3,8],[1,6,4],
                  [0,1,2],[1,4,2],[2,4,5],[5,4,6],[5,6,7],[7,6,8],
                  [7,8,3],[0,2,3],[3,2,7],[7,2,5]	]);
      }
    }
  } else {
    echo("Step Degrees too aggresive, the thread will not be made!!");
    echo("Try to increase de value for the degrees and/or...");
    echo(" decrease the pitch value and/or...");
    echo(" increase the outer diameter value.");
  }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
module hex_head(hg,df)  {
  //hg:  Height 
  //df:  Distance between flats
	rd0=df/2/sin(60);
	x0=0;	x1=df/2;	x2=x1+hg/2;
	y0=0;	y1=hg/2;	y2=hg;

	intersection() {
	  cylinder(h=hg, r=rd0, $fn=6, center=false);

		rotate_extrude(convexity=10, $fn=6*round(df*PI/6/0.5))
		polygon([ [x0,y0],[x1,y0],[x2,y1],[x1,y2],[x0,y2] ]);
	}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
module hex_countersink_ends(chg, cod, lf0, rs, hg) {
  //chg: Step height/2 (used to countersink the ends)  
  //cod: Outer diameter of the thread to match
  //lf0: Degrees (same as used for the screw_thread example)
  //rs: Resolution, you may want to set this to small values (quite high res) to minimize overhang issues
  //hg:  Height   
  translate([0,0,-0.1])
    cylinder(h=chg+0.01, 
             r1=cod/2, 
             r2=cod/2-(chg+0.1)*cos(lf0)/sin(lf0),
             $fn=floor(cod*PI/rs), center=false);

  translate([0,0,hg-chg+0.1])
    cylinder(h=chg+0.01, 
             r1=cod/2-(chg+0.1)*cos(lf0)/sin(lf0),
             r2=cod/2, 
             $fn=floor(cod*PI/rs), center=false);
}
